/********************************************************************
	created:	2013/05/28
	created:	28:5:2013   11:34
	author:		Hu
	
	purpose:	The demo files
*********************************************************************/
#include <d3d9.h>
#include <Windows.h>

HWND g_hWndMain = NULL;
HINSTANCE g_hInstanceApp = NULL;
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevi = NULL;

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

// The definition for the vertex
typedef struct _tagCustomVertex
{
	float x,y,z,rhw;
	DWORD color; 
}CUSTOMVERTEX;

HRESULT GameInit(  )
{
	// Create the Directx3D Object
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (g_pD3D == NULL)
	{
		return E_FAIL;
	}

	// Specify the application to behave
	D3DPRESENT_PARAMETERS	d3dpp;
	ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

	// Create the Direct3D Device
	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hWndMain,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pD3DDevi)))
	{
		return E_FAIL;
	}

	// Initialize the values of three vertices
	CUSTOMVERTEX vertices[]=
	{
		{150.0f,50.0.5f,1.0f,0x00ffff00},
		{200.0f,150.0f,0.5f,1.0f,0x0000ff00},
		{50.0f,250.0f,0.5f,1.0f,0x0000ffff}
	};

	// Create the vertex buffer
	if (g_pD3DDevi == NULL)
	{
		return E_FAIL;
	}

	g_pD3DDevi->CreateVertexBuffer();
	
	return NOERROR;
}

HRESULT GameShutdown(  )
{
	if (g_pD3DDevi)
	{
		g_pD3DDevi->Release();

	}
	if (g_pD3D)
	{
		g_pD3D->Release();
	}
	return NOERROR;
}

HRESULT GameMain(  )
{
	UpdateWindow(g_hWndMain);
	return NOERROR;
}

void Render()
{
	if (g_pD3DDevi == NULL)
	{
		return;
	}

	g_pD3DDevi->Clear( 0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);

	// Begin to render the scene
	g_pD3DDevi->BeginScene();

	// Rendering

	// End
	g_pD3DDevi->EndScene();

	g_pD3DDevi->Present(NULL,NULL,NULL,NULL);
}

LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	switch(msg)
	{
	case WM_PAINT:
		{
			Render();
		}
		return 0;
	case WM_DESTROY:
		break;
	case WM_QUIT:
		{
			if (IDOK == MessageBox(g_hWndMain,L"Are you sure to quit?",L"Tip",MB_OKCANCEL | MB_ICONWARNING))
			{
				PostQuitMessage(0);
				return 0;
			}
		}
		break;
	case WM_CLOSE:
		break;
	case WM_CHAR:
		break;
	case WM_MOUSEMOVE:
		break;
	case WM_LBUTTONUP:
		break;
	default:
		break;
	}

	return DefWindowProc(hWnd,msg,wParam,lParam);
}


int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
	// Initialise the window_class struct
	WNDCLASSEX wndClass;
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
	wndClass.lpszClassName = L"GMWNDClass";
	wndClass.lpszMenuName = NULL;
	wndClass.hInstance = hInstance;
	wndClass.hIcon = ::LoadIcon(NULL,IDI_WINLOGO);
	wndClass.hIconSm = ::LoadIcon(NULL,IDI_WINLOGO);
	wndClass.hCursor = ::LoadCursor(NULL,IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
	wndClass.cbWndExtra = 0;
	wndClass.cbClsExtra = 0;
	wndClass.lpfnWndProc = WinProc;

	g_hInstanceApp = hInstance;

	// Register the window_class
	RegisterClassEx(&wndClass);

	// Create the window
	g_hWndMain = CreateWindowEx(0,L"GMWNDClass",L"GMWnd",WS_OVERLAPPEDWINDOW | WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,800,600,NULL,NULL,hInstance,NULL);
	if (g_hWndMain == NULL)
	{
		return 0;
	}
	::ShowWindow(g_hWndMain,SW_SHOW);
	::UpdateWindow(g_hWndMain);

	// Initialize the game
	GameInit();

	// Deal with the message
	MSG msg;

	while(true)
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;

			TranslateMessage(&msg);

			DispatchMessage(&msg);
		}

		// Main loop
		GameMain();
	}

	// Shutdown the game
	GameShutdown();
	
	return 1;
}